package main.java.com.lee.complatablfuture;

import java.util.concurrent.*;

/**
 * @Description TODO
 * @Author winston
 * @DateTime 2022/3/4
 */
public class CompletableFutureDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3, r -> {
            Thread thread = new Thread(r);
            thread.setName("Winston_" + System.currentTimeMillis());
            return thread;
        });
        cal01();
        cal01(executorService);
        cal02();
        cal03();
        cal04();
        cal05();
        executorService.shutdown();
    }

    /**
     * 计算(1+1)*2, ForkJoin.pool
     */
    private static void cal01() {
        CompletableFuture.supplyAsync(() -> 1 + 1)
                .thenApply(i -> i * 2)
                .thenAccept(i->System.out.println(i));
    }

    /**
     * 计算(1+1)*2, ForkJoin.pool
     */
    private static void cal01(Executor executor) {

        CompletableFuture.supplyAsync(() -> 1 + 1, executor)
                .thenApply(i -> i * 2)
                .thenAcceptAsync(i -> System.out.println(i));
    }

    /**
     * 计算(1+2)*(2+3)
     */
    private static void cal02() {
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> 1 + 2);
        CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> 2 + 3);
        future01.thenCombine(future02, (i,j)->i*j)
                .thenAccept(i->System.out.println(i));

    }

    private static void cal02(Executor executor) {
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> 1 + 2, executor);
        CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> 2 + 3, executor);
        future01.thenCombine(future02, (i,j)->i*j)
                .thenAcceptAsync(i->System.out.println(i), executor);

    }

    /**
     * 计算(1+2)(3+4)(5+6)
     */
    private static void cal03() {
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> 1 + 2);
        CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> 3 + 4);
        CompletableFuture<Integer> future03 = CompletableFuture.supplyAsync(() -> 5 + 6);
        CompletableFuture.allOf(future01, future02, future03).join();
        CompletableFuture.supplyAsync(()-> {
            try {
                return future01.get()*future02.get()*future03.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            return 0;
        })
                .thenAcceptAsync(i->System.out.println(i));
    }

    /**
     * 计算(10+1)*3   或者  (10-1)*3
     */
    private static void cal04() {
        CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> 10 + 1);
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> 10 - 1);
        future01.applyToEither(future02, i->i*3)
                .thenAcceptAsync(i->System.out.println(i));
    }

    /**
     * 计算((1+2)*3)-5
     */
    private static void cal05() {
        CompletableFuture.supplyAsync(()->1+2)
                .thenCompose(i-> CompletableFuture.supplyAsync(()->i*3))
                .thenCompose(i->CompletableFuture.supplyAsync(()->i-5))
                .whenComplete((i, e)-> {
                    if (e != null) {
                        e.printStackTrace();
                    } else {
                        System.out.println(i);
                    }
                });
    }
}
